#ifndef BASE_TCP_PACKET_H
#define BASE_TCP_PACKET_H

#include "../../../Base/HasHeader.h"
#include "../../../Base/RecursiveLockingMutex.h"
#include <boost/asio/ip/tcp.hpp>
#include <vector>

#define MPN_TCP_PKT_MAX			1024
#define MPN_TCP_PKT_HEADER_MAX	128
#define MPN_TCP_PKT_FOOTER_MAX	128

using mp_base::HasHeader;
using mp_base::RecursiveLockingMutex;
using std::vector;

namespace mp_net
{
	/*!  */
	typedef unsigned int uint;

	/*!
	* @class	TcpPacketPart
	* @brief	Represents a part of a TCP packet that contains data
	*			of an object in char[] format.
	* @note		This should only be ran by the network thread. Mutex
	*			locking should be done on the object used to sync with
	*			the packet part.
	*/
	class TcpPacketPart : public HasHeader<char>
	{
	public:
		TcpPacketPart(){}
		virtual ~TcpPacketPart(){}

		char*	Packet(){return m_packet;}
		uint	PacketSize(){return m_packetSize; }
		void	Packet(char* packet){ m_packet = packet; }
		void	PacketSize(uint size){ m_packetSize = size; }

		/*!
		* Get the char array for the packet part.
		*/
		void	GetBuiltPacket(char* packet, uint& size);

		bool operator == ( TcpPacketPart const& part)
			{return false;}

	private:
		char*	m_packet;
		uint	m_packetSize;
	};
	
	/*!  */
	typedef vector<TcpPacketPart*> vPacketParts;

	/*!
	* @class	TcpPacket
	* @brief	Represents the full char array built from
	*			TcpPacketPart objects.
	* @note		This should only be ran by the network thread. Mutex
	*			locking should be done on the object used to sync with
	*			the packet part.
	*/
	class TcpPacket : public HasHeader<char>, public RecursiveLockingMutex
	{
	public:
		TcpPacket(){m_updated=false;}
		TcpPacket(const char* packetData)
			{ BuildFromPacket(packetData); m_updated=false;}
		virtual ~TcpPacket();

		void AddPacketPart(TcpPacketPart* packetPart);
		void RemovePacketPart(TcpPacketPart* packetPart, bool deletePart=false);
		void ClearPacketParts(){m_packetParts.clear();}
		
		/*!
		* Get the char array for the packet.
		*/
		void GetBuiltPacket(char* packet, uint& size);
		void SyncFromPacket();

		bool IsUpdated(){return m_updated;}
		void Updated(const bool status){m_updated = status;}

	private:
		void BuildFromPacket(const char* packetData);

		vPacketParts			m_packetParts;
		vPacketParts::iterator	m_packetPartsIndex;
		volatile bool			m_updated;
	};
}
#endif